package site_announcement

import (
	"context"
	"errors"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-user-service/infrastructure/repository/site_announcement"
	pb "git.mycaigou.com/gfyx/micro-gfyx-user-service/proto/micro_gfyx_user_service_proto/micro-gfyx-user-service"
	"git.myscrm.cn/golang/stark/v4"
	"time"
)

type SiteAnnouncementService struct {
	siteAnnouncementRepository site_announcement.SiteAnnouncementRepositoryIface
}

func NewSiteAnnouncementService(siteAnnouncementRepository site_announcement.SiteAnnouncementRepositoryIface) SiteAnnouncementServiceIface {
	return &SiteAnnouncementService{siteAnnouncementRepository: siteAnnouncementRepository}
}

func (s *SiteAnnouncementService) GetSiteAnnouncementList(ctx context.Context, request *pb.GetSiteAnnouncementListRequest) (*pb.GetSiteAnnouncementListResponse, error) {
	pageUtil := utils.PageInfo{
		PageSize: 0,
		Page:     0,
	}
	if request.Page > 0 && request.Page < 100 {
		pageUtil.Page = int(request.Page)
	} else {
		pageUtil.Page = 1
	}
	if request.PageSize > 0 && request.PageSize < 100 {
		pageUtil.PageSize = int(request.PageSize)
	} else {
		pageUtil.PageSize = 10
	}
	total, announcementList, err := s.siteAnnouncementRepository.QuerySiteAnnouncementList(ctx, map[string]interface{}{"is_deleted": constants.IsDeletedFalse}, &pageUtil, "created_on desc")
	if err != nil {
		stark.Logger.Errorf(ctx, "GetSiteAnnouncementList error: %v", err)
		return nil, err
	}
	resp := &pb.GetSiteAnnouncementListResponse{
		Total: total,
		List:  make([]*pb.SiteAnnouncementItem, 0),
	}
	for _, announcement := range announcementList {
		resp.List = append(resp.List, &pb.SiteAnnouncementItem{
			Id:        announcement.Id,
			Title:     announcement.Title,
			Content:   announcement.Content,
			Url:       announcement.Url,
			Cycle:     announcement.Cycle,
			StartTime: announcement.StartTime.Format("2006-01-02 15:04:05"),
			EndTime:   announcement.EndTime.Format("2006-01-02 15:04:05"),
			CreatedOn: announcement.CreatedOn.Format("2006-01-02 15:04:05"),
			CreatedBy: announcement.CreatedBy,
		})
	}
	return resp, nil
}

func (s *SiteAnnouncementService) GetSiteAnnouncementDetail(ctx context.Context, request *pb.GetSiteAnnouncementDetailRequest) (*pb.GetSiteAnnouncementDetailResponse, error) {
	detail, err := s.siteAnnouncementRepository.GetSiteAnnouncementDetail(ctx, request.Id)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetSiteAnnouncementDetail error: %v", err)
		return nil, err
	}
	return &pb.GetSiteAnnouncementDetailResponse{
		Id:        detail.Id,
		Title:     detail.Title,
		Content:   detail.Content,
		Url:       detail.Url,
		Cycle:     detail.Cycle,
		StartTime: detail.StartTime.Format("2006-01-02 15:04:05"),
		EndTime:   detail.EndTime.Format("2006-01-02 15:04:05"),
		CreatedBy: detail.CreatedBy,
		CreatedOn: detail.CreatedOn.Format("2006-01-02 15:04:05"),
	}, nil
}

func (s *SiteAnnouncementService) SaveSiteAnnouncement(ctx context.Context, request *pb.SaveSiteAnnouncementRequest) (*pb.SaveSiteAnnouncementResponse, error) {
	// 检查输入时间
	startTime, err := time.ParseInLocation("2006-01-02 15:04:05", request.StartTime, time.Local)
	if err != nil {
		return nil, errors.New("开始时间的格式不对：" + err.Error())
	}
	// 处理结束时间
	endTime, err := time.ParseInLocation("2006-01-02 15:04:05", request.EndTime, time.Local)
	if err != nil {
		return nil, errors.New("结束时间的格式不对：" + err.Error())
	}
	// 如果开始时间大于结束时间，则报错
	if startTime.After(endTime) || startTime.Equal(endTime) {
		return nil, errors.New("结束时间应该要大于等于开始时间")
	}

	// 检查标题不能重复
	isRepeat, _ := s.siteAnnouncementRepository.IsRepeatTitle(ctx, request.Title, request.Id)
	if isRepeat {
		return nil, errors.New("标题:【" + request.Title + "】重复，请更换标题名称")
	}
	// 构造保存数据
	po := &site_announcement.SiteAnnouncementPo{}
	if request.Id != 0 {
		po.Id = request.Id
	} else {
		po.CreatedBy = request.CreatedBy
		po.CreatedOn = time.Now()
	}
	po.Title = request.Title
	po.Content = request.Content
	po.Url = request.Url
	po.Cycle = request.Cycle
	po.StartTime = startTime
	po.EndTime = endTime
	po.ModifiedOn = time.Now()
	po.ModifiedBy = request.CreatedBy
	po.IsDeleted = constants.IsDeletedFalse
	announcement, err := s.siteAnnouncementRepository.SaveSiteAnnouncement(ctx, po)
	if err != nil {
		stark.Logger.Errorf(ctx, "保存弹窗公告失败：%s", err.Error())
		return nil, errors.New("保存弹窗公告失败")
	}

	return &pb.SaveSiteAnnouncementResponse{Id: announcement.Id}, nil
}

func (s *SiteAnnouncementService) DeleteSiteAnnouncement(ctx context.Context, request *pb.DeleteSiteAnnouncementRequest) (*pb.DeleteSiteAnnouncementResponse, error) {
	err := s.siteAnnouncementRepository.DeleteSiteAnnouncement(ctx, request.Id, request.ModifiedBy)
	if err != nil {
		return nil, err
	}
	return &pb.DeleteSiteAnnouncementResponse{}, nil
}

func (s *SiteAnnouncementService) SetSiteAnnouncementViewRecord(ctx context.Context, request *pb.SetSiteAnnouncementReadRequest) (*pb.SetSiteAnnouncementReadResponse, error) {
	// 查看站点是否存在
	detail, err := s.siteAnnouncementRepository.GetSiteAnnouncementDetail(ctx, request.SiteAnnouncementId)
	if err != nil {
		stark.Logger.Errorf(ctx, "SetSiteAnnouncementViewRecord error: %v", err)
		return nil, err
	}
	if detail.Id == 0 {
		return nil, errors.New("该公告不存在")
	}
	// 设置用户已经存在
	id, err := s.siteAnnouncementRepository.SetSiteAnnouncementViewRecord(ctx, request.SiteAnnouncementId, request.UserId, request.TenantCode)
	if err != nil {
		stark.Logger.Errorf(ctx, "SetSiteAnnouncementViewRecord error: %v", err)
		return nil, err
	}
	return &pb.SetSiteAnnouncementReadResponse{Id: id}, nil
}

func (s *SiteAnnouncementService) GetUserSiteAnnouncementList(ctx context.Context, request *pb.GetUserSiteAnnouncementListRequest) (*pb.GetUserSiteAnnouncementListResponse, error) {
	// 参数校验
	pageUtil := utils.PageInfo{
		PageSize: 0,
		Page:     0,
	}
	if request.Page > 0 && request.Page < 100 {
		pageUtil.Page = int(request.Page)
	} else {
		pageUtil.Page = 1
	}
	if request.PageSize > 0 && request.PageSize < 100 {
		pageUtil.PageSize = int(request.PageSize)
	} else {
		pageUtil.PageSize = 10
	}
	condition := map[string]interface{}{
		"current_time": time.Now().Format("2006-01-02 15:04:05"),
		"is_deleted":   constants.IsDeletedFalse,
	}
	// 获取用户读的 id
	record, err := s.siteAnnouncementRepository.GetUserViewRecord(ctx, request.UserId, request.TenantCode)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetUserViewRecord params: %v,error: %v", request, err)
		return nil, err
	}
	// 拼接参数
	if len(record) > 0 {
		condition["ids"] = record
	}

	total, announcementList, err := s.siteAnnouncementRepository.QuerySiteAnnouncementList(ctx, condition, &pageUtil, "created_on desc")
	if err != nil {
		stark.Logger.Errorf(ctx, "QuerySiteAnnouncementList params: %v,error: %v", condition, err)
		return nil, err
	}
	// 处理返回数据
	resp := &pb.GetUserSiteAnnouncementListResponse{
		Total: total,
		List:  make([]*pb.SiteAnnouncementItem, 0),
	}

	for _, announcement := range announcementList {
		resp.List = append(resp.List, &pb.SiteAnnouncementItem{
			Id:        announcement.Id,
			Title:     announcement.Title,
			Content:   announcement.Content,
			Url:       announcement.Url,
			Cycle:     announcement.Cycle,
			StartTime: announcement.StartTime.Format("2006-01-02 15:04:05"),
			EndTime:   announcement.EndTime.Format("2006-01-02 15:04:05"),
			CreatedOn: announcement.CreatedOn.Format("2006-01-02 15:04:05"),
			CreatedBy: announcement.CreatedBy,
		})
	}
	return resp, nil
}
